package com.waikuai.shop.service.impl;

import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.waikuai.shop.dto.EmployeeFormDTO;
import com.waikuai.shop.dto.EmployeeQueryDTO;
import com.waikuai.shop.dto.RoleInfo;
import com.waikuai.shop.dto.UpdatePasswordDTO;
import com.waikuai.shop.dto.UpdatePaymentPasswordDTO;
import com.waikuai.shop.dto.UpdateProfileDTO;
import com.waikuai.shop.dto.UserInfo;
import com.waikuai.shop.entity.Role;
import com.waikuai.shop.entity.User;
import com.waikuai.shop.exception.BusinessException;
import com.waikuai.shop.mapper.PermissionMapper;
import com.waikuai.shop.mapper.RoleMapper;
import com.waikuai.shop.mapper.UserMapper;
import com.waikuai.shop.service.UserService;
import com.waikuai.shop.vo.EmployeeVO;
import com.waikuai.shop.vo.ImportResultVO;
import com.waikuai.shop.dto.EmployeeImportDTO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;

import java.io.IOException;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import javax.servlet.http.HttpServletResponse;
import java.util.UUID;
import java.util.ArrayList;

import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 用户服务实现类
 * @author waikuai
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class UserServiceImpl implements UserService {

    private final UserMapper userMapper;
    private final RoleMapper roleMapper;
    private final PermissionMapper permissionMapper;
    private final PasswordEncoder passwordEncoder = new BCryptPasswordEncoder();

    @Override
    public User findById(Long userId) {
        if (userId == null) {
            return null;
        }
        return userMapper.selectById(userId);
    }

    @Override
    public User findByUsername(String username) {
        if (StrUtil.isBlank(username)) {
            return null;
        }
        return userMapper.findByUsername(username);
    }

    @Override
    public User findByAccount(String account) {
        if (StrUtil.isBlank(account)) {
            return null;
        }
        return userMapper.findByAccount(account);
    }

    @Override
    @Transactional(readOnly = true)
    public UserInfo getUserInfo(Long userId) {
        if (userId == null) {
            throw new BusinessException("用户ID不能为空");
        }

        // 查询用户基本信息
        User user = findById(userId);
        if (user == null) {
            throw new BusinessException("用户不存在");
        }

        // 构建用户信息
        UserInfo userInfo = new UserInfo();
        BeanUtils.copyProperties(user, userInfo);

        // 查询用户角色
        List<Role> roles = roleMapper.findByUserId(userId);
        userInfo.setRoles(roles.stream()
                .map(role -> {
                    RoleInfo roleInfo = new RoleInfo();
                    BeanUtils.copyProperties(role, roleInfo);
                    return roleInfo;
                })
                .collect(Collectors.toList()));

        // 查询用户权限
        List<String> permissions = getUserPermissions(userId);
        userInfo.setPermissions(permissions);

        return userInfo;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateLastLoginInfo(Long userId, String loginIp) {
        if (userId != null) {
            userMapper.updateLastLoginInfo(userId, loginIp);
            log.debug("更新用户最后登录信息: userId={}, ip={}", userId, loginIp);
        }
    }

    @Override
    public boolean existsByAccount(String account) {
        if (StrUtil.isBlank(account)) {
            return false;
        }

        User user = findByAccount(account);
        return user != null;
    }

    /**
     * 获取用户权限列表
     * @param userId 用户ID
     * @return 权限编码列表
     */
    private List<String> getUserPermissions(Long userId) {
        List<com.waikuai.shop.entity.Permission> permissions = permissionMapper.findByUserId(userId);
        return permissions.stream()
                .map(com.waikuai.shop.entity.Permission::getPermissionCode)
                .collect(Collectors.toList());
    }

    // ==================== 员工管理方法实现 ====================

    @Override
    @Transactional(readOnly = true)
    public IPage<EmployeeVO> getEmployeePage(EmployeeQueryDTO queryDTO) {
        log.info("分页查询员工列表，查询条件: {}", queryDTO);

        // 构建分页对象
        Page<User> page = new Page<>(queryDTO.getCurrent(), queryDTO.getSize());

        // 构建查询条件
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        
        // 关键词查询（姓名或工号）
        if (StrUtil.isNotBlank(queryDTO.getKeyword())) {
            wrapper.and(w -> w.like(User::getRealName, queryDTO.getKeyword())
                    .or().like(User::getEmployeeNo, queryDTO.getKeyword())
                    .or().like(User::getUsername, queryDTO.getKeyword()));
        }

        // 部门查询
        if (StrUtil.isNotBlank(queryDTO.getDepartment())) {
            wrapper.eq(User::getDepartment, queryDTO.getDepartment());
        }

        // 状态查询
        if (queryDTO.getStatus() != null) {
            wrapper.eq(User::getStatus, queryDTO.getStatus());
        }

        // 按创建时间倒序
        wrapper.orderByDesc(User::getCreateTime);

        // 执行分页查询
        IPage<User> userPage = userMapper.selectPage(page, wrapper);

        // 转换为EmployeeVO
        IPage<EmployeeVO> employeePage = new Page<>(userPage.getCurrent(), userPage.getSize(), userPage.getTotal());
        List<EmployeeVO> employeeList = userPage.getRecords().stream()
                .map(this::convertToEmployeeVO)
                .collect(Collectors.toList());
        employeePage.setRecords(employeeList);

        return employeePage;
    }

    @Override
    @Transactional(readOnly = true)
    public EmployeeVO getEmployeeById(Long id) {
        log.info("获取员工详情: id={}", id);

        User user = userMapper.selectById(id);
        if (user == null) {
            throw new BusinessException("员工不存在");
        }

        return convertToEmployeeVO(user);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addEmployee(EmployeeFormDTO formDTO) {
        log.info("新增员工: {}", formDTO.getUsername());

        // 检查用户名是否已存在
        if (existsByUsername(formDTO.getUsername())) {
            throw new BusinessException("用户名已存在");
        }

        // 检查工号是否已存在
        if (StrUtil.isNotBlank(formDTO.getEmployeeNo()) && existsByEmployeeNo(formDTO.getEmployeeNo())) {
            throw new BusinessException("员工工号已存在");
        }

        // 检查手机号是否已存在
        if (StrUtil.isNotBlank(formDTO.getPhone()) && existsByPhone(formDTO.getPhone())) {
            throw new BusinessException("手机号已存在");
        }

        // 创建用户对象
        User user = new User();
        BeanUtils.copyProperties(formDTO, user);

        // 如果没有提供密码，使用默认密码（加密后的"123456"）
        if (StrUtil.isBlank(user.getPassword())) {
            user.setPassword(passwordEncoder.encode("123456"));
        } else {
            // 如果提供了密码，进行加密
            user.setPassword(passwordEncoder.encode(user.getPassword()));
        }
        
        // 设置默认支付密码（加密后的"123456"）
        if (StrUtil.isBlank(user.getPaymentPassword())) {
            user.setPaymentPassword(passwordEncoder.encode("123456"));
        }

        // 如果没有提供工号，自动生成
        if (StrUtil.isBlank(user.getEmployeeNo())) {
            user.setEmployeeNo(generateEmployeeNo());
        }

        // 设置默认值
        if (user.getStatus() == null) {
            user.setStatus(1); // 默认启用
        }
        if (user.getAccountBalance() == null) {
            user.setAccountBalance(0.0);
        }

        // 插入用户
        userMapper.insert(user);

        // 分配角色（如果提供了角色ID）
        if (formDTO.getRoleIds() != null && formDTO.getRoleIds().length > 0) {
            for (Long roleId : formDTO.getRoleIds()) {
                userMapper.insertUserRole(user.getId(), roleId);
            }
        } else {
            // 默认分配员工角色（角色ID=2）
            userMapper.insertUserRole(user.getId(), 2L);
        }

        log.info("新增员工成功: id={}, username={}", user.getId(), user.getUsername());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateEmployee(EmployeeFormDTO formDTO) {
        log.info("更新员工信息: id={}", formDTO.getId());

        // 检查员工是否存在
        User existUser = userMapper.selectById(formDTO.getId());
        if (existUser == null) {
            throw new BusinessException("员工不存在");
        }

        // 检查用户名是否被其他人使用
        if (!existUser.getUsername().equals(formDTO.getUsername()) 
                && existsByUsername(formDTO.getUsername())) {
            throw new BusinessException("用户名已被其他人使用");
        }

        // 检查工号是否被其他人使用
        if (StrUtil.isNotBlank(formDTO.getEmployeeNo()) 
                && !formDTO.getEmployeeNo().equals(existUser.getEmployeeNo())
                && existsByEmployeeNo(formDTO.getEmployeeNo())) {
            throw new BusinessException("员工工号已被其他人使用");
        }

        // 检查手机号是否被其他人使用
        if (StrUtil.isNotBlank(formDTO.getPhone()) 
                && !formDTO.getPhone().equals(existUser.getPhone())
                && existsByPhone(formDTO.getPhone())) {
            throw new BusinessException("手机号已被其他人使用");
        }

        // 更新用户信息
        User user = new User();
        BeanUtils.copyProperties(formDTO, user);
        
        // 如果提供了新密码，则加密后更新密码
        if (StrUtil.isBlank(formDTO.getPassword())) {
            user.setPassword(null); // 不更新密码
        } else {
            user.setPassword(passwordEncoder.encode(formDTO.getPassword()));
        }

        userMapper.updateById(user);

        // 更新角色分配
        if (formDTO.getRoleIds() != null) {
            // 删除旧的角色关联
            userMapper.deleteUserRoles(user.getId());
            // 插入新的角色关联
            for (Long roleId : formDTO.getRoleIds()) {
                userMapper.insertUserRole(user.getId(), roleId);
            }
        }

        log.info("更新员工信息成功: id={}", user.getId());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteEmployee(Long id) {
        log.info("删除员工: id={}", id);

        User user = userMapper.selectById(id);
        if (user == null) {
            throw new BusinessException("员工不存在");
        }

        // 逻辑删除
        userMapper.deleteById(id);

        log.info("删除员工成功: id={}", id);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void batchDeleteEmployees(List<Long> ids) {
        log.info("批量删除员工: ids={}", ids);

        if (ids == null || ids.isEmpty()) {
            throw new BusinessException("请选择要删除的员工");
        }

        userMapper.deleteBatchIds(ids);

        log.info("批量删除员工成功，共删除{}个", ids.size());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateEmployeeStatus(Long id, Integer status) {
        log.info("更新员工状态: id={}, status={}", id, status);

        User user = userMapper.selectById(id);
        if (user == null) {
            throw new BusinessException("员工不存在");
        }

        user.setStatus(status);
        userMapper.updateById(user);

        log.info("更新员工状态成功: id={}", id);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void batchUpdateEmployeeStatus(List<Long> ids, Integer status) {
        log.info("批量更新员工状态: ids={}, status={}", ids, status);

        if (ids == null || ids.isEmpty()) {
            throw new BusinessException("请选择要操作的员工");
        }

        for (Long id : ids) {
            User user = new User();
            user.setId(id);
            user.setStatus(status);
            userMapper.updateById(user);
        }

        log.info("批量更新员工状态成功，共更新{}个", ids.size());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String resetEmployeePassword(Long id) {
        log.info("重置员工密码: id={}", id);

        User user = userMapper.selectById(id);
        if (user == null) {
            throw new BusinessException("员工不存在");
        }

        // 生成随机密码（6位数字）
        String newPassword = RandomUtil.randomNumbers(6);
        
        // 加密密码后存储
        user.setPassword(passwordEncoder.encode(newPassword));
        userMapper.updateById(user);

        log.info("重置员工密码成功: id={}, newPassword={}", id, newPassword);
        return newPassword;
    }

    @Override
    @Transactional(readOnly = true)
    public List<String> getAllDepartments() {
        log.info("获取所有部门列表");
        
        List<String> departments = userMapper.selectAllDepartments();
        
        // 过滤空值
        return departments.stream()
                .filter(StrUtil::isNotBlank)
                .distinct()
                .collect(Collectors.toList());
    }

    /**
     * 转换User为EmployeeVO
     */
    private EmployeeVO convertToEmployeeVO(User user) {
        EmployeeVO vo = new EmployeeVO();
        BeanUtils.copyProperties(user, vo);

        // 查询用户角色
        List<Role> roles = roleMapper.findByUserId(user.getId());
        vo.setRoles(roles.stream()
                .map(role -> {
                    RoleInfo roleInfo = new RoleInfo();
                    BeanUtils.copyProperties(role, roleInfo);
                    return roleInfo;
                })
                .collect(Collectors.toList()));

        return vo;
    }

    /**
     * 检查用户名是否已存在
     */
    private boolean existsByUsername(String username) {
        if (StrUtil.isBlank(username)) {
            return false;
        }
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(User::getUsername, username);
        return userMapper.selectCount(wrapper) > 0;
    }

    /**
     * 检查员工工号是否已存在
     */
    private boolean existsByEmployeeNo(String employeeNo) {
        if (StrUtil.isBlank(employeeNo)) {
            return false;
        }
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(User::getEmployeeNo, employeeNo);
        return userMapper.selectCount(wrapper) > 0;
    }

    /**
     * 检查手机号是否已存在
     */
    private boolean existsByPhone(String phone) {
        if (StrUtil.isBlank(phone)) {
            return false;
        }
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(User::getPhone, phone);
        return userMapper.selectCount(wrapper) > 0;
    }

    /**
     * 生成员工工号
     */
    private String generateEmployeeNo() {
        // 格式：EMP + 年月 + 4位随机数
        String prefix = "EMP" + java.time.LocalDate.now().format(java.time.format.DateTimeFormatter.ofPattern("yyyyMM"));
        String randomNum = RandomUtil.randomNumbers(4);
        return prefix + randomNum;
    }

    // ==================== 个人信息管理相关方法实现 ====================

    @Override
    public EmployeeVO getMyProfile(Long userId) {
        log.info("获取当前用户信息: userId={}", userId);
        
        User user = userMapper.selectById(userId);
        if (user == null) {
            throw new BusinessException("用户不存在");
        }
        
        return convertToEmployeeVO(user);
    }

    @Override
    @Transactional
    public void updateMyProfile(UpdateProfileDTO dto, Long userId) {
        log.info("更新个人信息: userId={}, dto={}", userId, dto);
        
        User user = userMapper.selectById(userId);
        if (user == null) {
            throw new BusinessException("用户不存在");
        }
        
        // 验证用户只能修改自己的信息
        if (!user.getId().equals(userId)) {
            throw new BusinessException("只能修改自己的信息");
        }
        
        // 检查手机号是否被其他用户使用
        if (StrUtil.isNotBlank(dto.getPhone()) && !dto.getPhone().equals(user.getPhone())) {
            if (existsByPhone(dto.getPhone())) {
                throw new BusinessException("手机号已被其他用户使用");
            }
        }
        
        // 检查邮箱是否被其他用户使用
        if (StrUtil.isNotBlank(dto.getEmail()) && !dto.getEmail().equals(user.getEmail())) {
            LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(User::getEmail, dto.getEmail());
            wrapper.ne(User::getId, userId);
            if (userMapper.selectCount(wrapper) > 0) {
                throw new BusinessException("邮箱已被其他用户使用");
            }
        }
        
        // 更新信息
        if (StrUtil.isNotBlank(dto.getPhone())) {
            user.setPhone(dto.getPhone());
        }
        if (StrUtil.isNotBlank(dto.getEmail())) {
            user.setEmail(dto.getEmail());
        }
        if (dto.getBirthday() != null) {
            user.setBirthday(dto.getBirthday().toString());
        }
        if (StrUtil.isNotBlank(dto.getAvatar())) {
            user.setAvatar(dto.getAvatar());
        }
        
        user.setUpdateTime(LocalDateTime.now());
        userMapper.updateById(user);
        
        log.info("个人信息更新成功: userId={}", userId);
    }

    @Override
    @Transactional
    public void updateMyPassword(UpdatePasswordDTO dto, Long userId) {
        log.info("修改密码: userId={}", userId);
        
        User user = userMapper.selectById(userId);
        if (user == null) {
            throw new BusinessException("用户不存在");
        }
        
        // 验证用户只能修改自己的密码
        if (!user.getId().equals(userId)) {
            throw new BusinessException("只能修改自己的密码");
        }
        
        // 验证旧密码
        if (!passwordEncoder.matches(dto.getOldPassword(), user.getPassword())) {
            throw new BusinessException("旧密码不正确");
        }
        
        // 验证新密码和确认密码是否一致
        if (!dto.getNewPassword().equals(dto.getConfirmPassword())) {
            throw new BusinessException("新密码和确认密码不一致");
        }
        
        // 加密新密码并更新
        String encodedPassword = passwordEncoder.encode(dto.getNewPassword());
        user.setPassword(encodedPassword);
        user.setUpdateTime(LocalDateTime.now());
        userMapper.updateById(user);
        
        log.info("密码修改成功: userId={}", userId);
    }
    
    @Override
    @Transactional
    public void updateMyPaymentPassword(UpdatePaymentPasswordDTO dto, Long userId) {
        log.info("修改支付密码: userId={}", userId);
        
        User user = userMapper.selectById(userId);
        if (user == null) {
            throw new BusinessException("用户不存在");
        }
        
        // 验证用户只能修改自己的支付密码
        if (!user.getId().equals(userId)) {
            throw new BusinessException("只能修改自己的支付密码");
        }
        
        // 验证旧支付密码
        if (StrUtil.isBlank(user.getPaymentPassword())) {
            throw new BusinessException("尚未设置支付密码");
        }
        if (!passwordEncoder.matches(dto.getOldPaymentPassword(), user.getPaymentPassword())) {
            throw new BusinessException("旧支付密码不正确");
        }
        
        // 验证新支付密码和确认密码是否一致
        if (!dto.getNewPaymentPassword().equals(dto.getConfirmPaymentPassword())) {
            throw new BusinessException("新支付密码和确认密码不一致");
        }
        
        // 加密新支付密码并更新
        String encodedPaymentPassword = passwordEncoder.encode(dto.getNewPaymentPassword());
        user.setPaymentPassword(encodedPaymentPassword);
        user.setUpdateTime(LocalDateTime.now());
        userMapper.updateById(user);
        
        log.info("支付密码修改成功: userId={}", userId);
    }
    
    @Override
    public String uploadAvatar(MultipartFile file, Long userId) {
        try {
            // 验证文件
            if (file.isEmpty()) {
                throw new RuntimeException("上传文件不能为空");
            }
            
            // 验证文件类型
            String contentType = file.getContentType();
            if (contentType == null || !contentType.startsWith("image/")) {
                throw new RuntimeException("只能上传图片文件");
            }
            
            // 验证文件大小（限制为5MB）
            if (file.getSize() > 5 * 1024 * 1024) {
                throw new RuntimeException("图片大小不能超过5MB");
            }
            
            // 创建上传目录
            String uploadDir = "backend/src/main/resources/static/avatars";
            Path uploadPath = Paths.get(uploadDir);
            if (!Files.exists(uploadPath)) {
                Files.createDirectories(uploadPath);
            }
            
            // 生成唯一文件名
            String originalFilename = file.getOriginalFilename();
            String extension = originalFilename.substring(originalFilename.lastIndexOf("."));
            String filename = UUID.randomUUID().toString() + extension;
            
            // 保存文件
            Path filePath = uploadPath.resolve(filename);
            Files.copy(file.getInputStream(), filePath);
            
            // 生成访问URL
            String avatarUrl = "/avatars/" + filename;
            
            // 更新用户头像
            User user = userMapper.selectById(userId);
            if (user == null) {
                throw new RuntimeException("用户不存在");
            }
            
            user.setAvatar(avatarUrl);
            userMapper.updateById(user);
            
            log.info("头像上传成功，用户ID: {}, 头像URL: {}", userId, avatarUrl);
            return avatarUrl;
            
        } catch (IOException e) {
            log.error("头像上传失败: {}", e.getMessage(), e);
            throw new RuntimeException("头像上传失败: " + e.getMessage());
        }
    }

    // ==================== Excel导入相关方法实现 ====================

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ImportResultVO importEmployees(MultipartFile file) {
        log.info("开始导入员工Excel文件");
        
        ImportResultVO result = new ImportResultVO();
        List<ImportResultVO.FailDetail> failDetails = new ArrayList<>();
        int successCount = 0;
        
        try {
            // 检查文件
            if (file == null || file.isEmpty()) {
                throw new BusinessException("文件不能为空");
            }
            
            String filename = file.getOriginalFilename();
            if (filename == null || (!filename.endsWith(".xls") && !filename.endsWith(".xlsx"))) {
                throw new BusinessException("文件格式错误，只支持.xls和.xlsx格式");
            }
            
            // 读取Excel文件
            Workbook workbook;
            if (filename.endsWith(".xlsx")) {
                workbook = new XSSFWorkbook(file.getInputStream());
            } else {
                workbook = new HSSFWorkbook(file.getInputStream());
            }
            
            Sheet sheet = workbook.getSheetAt(0);
            if (sheet == null) {
                throw new BusinessException("Excel文件无效");
            }
            
            // 解析数据（从第2行开始，第1行是表头）
            int totalRows = sheet.getLastRowNum();
            for (int i = 1; i <= totalRows; i++) {
                Row row = sheet.getRow(i);
                if (row == null) {
                    continue;
                }
                
                try {
                    EmployeeImportDTO dto = parseRow(row);
                    
                    // 验证必填字段
                    validateImportDTO(dto, i + 1);
                    
                    // 检查用户名是否已存在
                    if (existsByUsername(dto.getUsername())) {
                        throw new BusinessException("用户名已存在: " + dto.getUsername());
                    }
                    
                    // 检查工号是否已存在
                    if (StrUtil.isNotBlank(dto.getEmployeeNo()) && existsByEmployeeNo(dto.getEmployeeNo())) {
                        throw new BusinessException("员工工号已存在: " + dto.getEmployeeNo());
                    }
                    
                    // 检查手机号是否已存在
                    if (StrUtil.isNotBlank(dto.getPhone()) && existsByPhone(dto.getPhone())) {
                        throw new BusinessException("手机号已存在: " + dto.getPhone());
                    }
                    
                    // 创建用户
                    User user = new User();
                    user.setEmployeeNo(dto.getEmployeeNo());
                    user.setUsername(dto.getUsername());
                    user.setRealName(dto.getRealName());
                    user.setDepartment(dto.getDepartment());
                    user.setPosition(dto.getPosition());
                    user.setPhone(dto.getPhone());
                    user.setEmail(dto.getEmail());
                    
                    // 处理性别（男/女/未知 -> 1/2/0）
                    if (StrUtil.isNotBlank(dto.getGender())) {
                        switch (dto.getGender()) {
                            case "男":
                                user.setGender(1);
                                break;
                            case "女":
                                user.setGender(2);
                                break;
                            default:
                                user.setGender(0);
                                break;
                        }
                    }
                    
                    // 处理生日
                    if (StrUtil.isNotBlank(dto.getBirthday())) {
                        user.setBirthday(dto.getBirthday());
                    }
                    
                    // 设置默认值
                    user.setPassword(passwordEncoder.encode("123456")); // 默认密码（加密）
                    user.setPaymentPassword(passwordEncoder.encode("123456")); // 默认支付密码（加密）
                    user.setStatus(1); // 默认启用
                    user.setAccountBalance(0.0);
                    
                    // 插入用户
                    userMapper.insert(user);
                    
                    // 分配默认员工角色（角色ID=2）
                    userMapper.insertUserRole(user.getId(), 2L);
                    
                    successCount++;
                    log.info("导入员工成功: {}", dto.getRealName());
                    
                } catch (Exception e) {
                    log.error("导入员工失败，第{}行: {}", i + 1, e.getMessage());
                    
                    ImportResultVO.FailDetail detail = new ImportResultVO.FailDetail();
                    detail.setRowNum(i + 1);
                    detail.setReason(e.getMessage());
                    detail.setData(getRowData(row));
                    failDetails.add(detail);
                }
            }
            
            workbook.close();
            
            result.setSuccessCount(successCount);
            result.setFailCount(failDetails.size());
            result.setTotalCount(totalRows);
            result.setFailDetails(failDetails);
            
            log.info("导入完成：成功{}条，失败{}条", successCount, failDetails.size());
            
            return result;
            
        } catch (Exception e) {
            log.error("导入员工Excel失败: {}", e.getMessage(), e);
            throw new BusinessException("导入失败: " + e.getMessage());
        }
    }

    @Override
    public void downloadTemplate(HttpServletResponse response) {
        log.info("开始下载Excel模板");
        
        try {
            // 创建工作簿
            Workbook workbook = new XSSFWorkbook();
            Sheet sheet = workbook.createSheet("员工信息");
            
            // 创建单元格样式
            CellStyle headerStyle = workbook.createCellStyle();
            Font headerFont = workbook.createFont();
            headerFont.setBold(true);
            headerFont.setFontHeightInPoints((short) 12);
            headerFont.setColor(org.apache.poi.ss.usermodel.IndexedColors.WHITE.getIndex());
            headerStyle.setFont(headerFont);
            headerStyle.setFillForegroundColor(org.apache.poi.ss.usermodel.IndexedColors.DARK_BLUE.getIndex());
            headerStyle.setFillPattern(org.apache.poi.ss.usermodel.FillPatternType.SOLID_FOREGROUND);
            headerStyle.setAlignment(org.apache.poi.ss.usermodel.HorizontalAlignment.CENTER);
            headerStyle.setVerticalAlignment(org.apache.poi.ss.usermodel.VerticalAlignment.CENTER);
            headerStyle.setBorderBottom(org.apache.poi.ss.usermodel.BorderStyle.THIN);
            headerStyle.setBorderTop(org.apache.poi.ss.usermodel.BorderStyle.THIN);
            headerStyle.setBorderLeft(org.apache.poi.ss.usermodel.BorderStyle.THIN);
            headerStyle.setBorderRight(org.apache.poi.ss.usermodel.BorderStyle.THIN);
            
            CellStyle dataStyle = workbook.createCellStyle();
            dataStyle.setBorderBottom(org.apache.poi.ss.usermodel.BorderStyle.THIN);
            dataStyle.setBorderTop(org.apache.poi.ss.usermodel.BorderStyle.THIN);
            dataStyle.setBorderLeft(org.apache.poi.ss.usermodel.BorderStyle.THIN);
            dataStyle.setBorderRight(org.apache.poi.ss.usermodel.BorderStyle.THIN);
            
            // 创建表头
            Row headerRow = sheet.createRow(0);
            String[] headers = {"工号", "用户名", "真实姓名", "部门", "职位", "手机号", "邮箱", "性别", "生日"};
            for (int i = 0; i < headers.length; i++) {
                Cell cell = headerRow.createCell(i);
                cell.setCellValue(headers[i]);
                cell.setCellStyle(headerStyle);
            }
            
            // 创建示例数据行1
            Row exampleRow1 = sheet.createRow(1);
            String[] exampleData1 = {
                "EMP001", "zhangsan", "张三", "技术部", "工程师", "13800138000", "zhangsan@example.com", "男", "1990-01-01"
            };
            for (int i = 0; i < exampleData1.length; i++) {
                Cell cell = exampleRow1.createCell(i);
                cell.setCellValue(exampleData1[i]);
                cell.setCellStyle(dataStyle);
            }
            
            // 创建示例数据行2
            Row exampleRow2 = sheet.createRow(2);
            String[] exampleData2 = {
                "EMP002", "lisi", "李四", "销售部", "销售经理", "13900139000", "lisi@example.com", "女", "1992-05-15"
            };
            for (int i = 0; i < exampleData2.length; i++) {
                Cell cell = exampleRow2.createCell(i);
                cell.setCellValue(exampleData2[i]);
                cell.setCellStyle(dataStyle);
            }
            
            // 设置表头行高
            headerRow.setHeightInPoints(20);
            
            // 设置列宽
            sheet.setColumnWidth(0, 4000);  // 工号
            sheet.setColumnWidth(1, 4500);  // 用户名
            sheet.setColumnWidth(2, 4500);  // 真实姓名
            sheet.setColumnWidth(3, 4000);  // 部门
            sheet.setColumnWidth(4, 4000);  // 职位
            sheet.setColumnWidth(5, 5000);  // 手机号
            sheet.setColumnWidth(6, 5000);  // 邮箱
            sheet.setColumnWidth(7, 3000);  // 性别
            sheet.setColumnWidth(8, 4000);  // 生日
            
            // 重置响应
            response.reset();
            
            // 设置CORS响应头（在reset之后设置）
            response.setHeader("Access-Control-Allow-Origin", "*");
            response.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
            response.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization");
            response.setHeader("Access-Control-Allow-Credentials", "true");
            response.setHeader("Access-Control-Max-Age", "3600");
            
            // 设置内容类型
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            response.setCharacterEncoding("UTF-8");
            
            // 防止缓存
            response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate");
            response.setHeader("Pragma", "no-cache");
            response.setHeader("Expires", "0");
            
            String fileName = new String("员工导入模板.xlsx".getBytes("UTF-8"), "ISO-8859-1");
            response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
            
            // 输出文件
            try (OutputStream outputStream = response.getOutputStream()) {
                workbook.write(outputStream);
                outputStream.flush();
            } finally {
                workbook.close();
            }
            
            log.info("Excel模板下载成功");
            
        } catch (IOException e) {
            log.error("下载Excel模板失败: {}", e.getMessage(), e);
            try {
                if (!response.isCommitted()) {
                    response.reset();
                    response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
                    response.setContentType("application/json;charset=UTF-8");
                    response.getWriter().write("{\"code\":500,\"message\":\"下载模板失败\"}");
                }
            } catch (Exception ignored) {
            }
        } catch (Exception e) {
            log.error("下载Excel模板失败: {}", e.getMessage(), e);
            try {
                if (!response.isCommitted()) {
                    response.reset();
                    response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
                    response.setContentType("application/json;charset=UTF-8");
                    response.getWriter().write("{\"code\":500,\"message\":\"下载模板失败\"}");
                }
            } catch (Exception ignored) {
            }
        }
    }

    /**
     * 解析Excel行数据
     */
    private EmployeeImportDTO parseRow(Row row) {
        EmployeeImportDTO dto = new EmployeeImportDTO();
        
        dto.setEmployeeNo(getCellValue(row, 0));
        dto.setUsername(getCellValue(row, 1));
        dto.setRealName(getCellValue(row, 2));
        dto.setDepartment(getCellValue(row, 3));
        dto.setPosition(getCellValue(row, 4));
        dto.setPhone(getCellValue(row, 5));
        dto.setEmail(getCellValue(row, 6));
        dto.setGender(getCellValue(row, 7));
        dto.setBirthday(getCellValue(row, 8));
        
        return dto;
    }

    /**
     * 获取单元格值
     */
    private String getCellValue(Row row, int cellIndex) {
        Cell cell = row.getCell(cellIndex);
        if (cell == null) {
            return "";
        }
        
        switch (cell.getCellType()) {
            case STRING:
                return cell.getStringCellValue().trim();
            case NUMERIC:
                if (DateUtil.isCellDateFormatted(cell)) {
                    return cell.getDateCellValue().toString();
                } else {
                    return String.valueOf((long) cell.getNumericCellValue());
                }
            case BOOLEAN:
                return String.valueOf(cell.getBooleanCellValue());
            case FORMULA:
                return cell.getCellFormula();
            default:
                return "";
        }
    }

    /**
     * 获取行数据（用于错误详情）
     */
    private String getRowData(Row row) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < row.getLastCellNum(); i++) {
            if (i > 0) {
                sb.append(", ");
            }
            sb.append(getCellValue(row, i));
        }
        return sb.toString();
    }

    /**
     * 验证导入DTO
     */
    private void validateImportDTO(EmployeeImportDTO dto, int rowNum) {
        if (StrUtil.isBlank(dto.getEmployeeNo())) {
            throw new BusinessException("工号不能为空");
        }
        if (StrUtil.isBlank(dto.getUsername())) {
            throw new BusinessException("用户名不能为空");
        }
        if (StrUtil.isBlank(dto.getRealName())) {
            throw new BusinessException("真实姓名不能为空");
        }
        
        // 验证手机号格式
        if (StrUtil.isNotBlank(dto.getPhone()) && !dto.getPhone().matches("^1[3-9]\\d{9}$")) {
            throw new BusinessException("手机号格式不正确: " + dto.getPhone());
        }
        
        // 验证邮箱格式
        if (StrUtil.isNotBlank(dto.getEmail()) && !dto.getEmail().matches("^[\\w-\\.]+@([\\w-]+\\.)+[\\w-]{2,4}$")) {
            throw new BusinessException("邮箱格式不正确: " + dto.getEmail());
        }
        
        // 验证生日格式
        if (StrUtil.isNotBlank(dto.getBirthday()) && !dto.getBirthday().matches("^\\d{4}-\\d{2}-\\d{2}$")) {
            throw new BusinessException("生日格式不正确，应为YYYY-MM-DD: " + dto.getBirthday());
        }
    }

    @Override
    public void exportEmployees(EmployeeQueryDTO queryDTO, HttpServletResponse response) {
        log.info("开始导出员工数据: {}", queryDTO);
        
        try {
            // 创建查询条件
            LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(User::getDeleted, 0); // 未删除
            
            // 根据筛选条件构建查询
            if (StrUtil.isNotBlank(queryDTO.getKeyword())) {
                wrapper.and(w -> w
                    .like(User::getRealName, queryDTO.getKeyword())
                    .or()
                    .like(User::getEmployeeNo, queryDTO.getKeyword())
                );
            }
            
            if (StrUtil.isNotBlank(queryDTO.getDepartment())) {
                wrapper.eq(User::getDepartment, queryDTO.getDepartment());
            }
            
            if (queryDTO.getStatus() != null) {
                wrapper.eq(User::getStatus, queryDTO.getStatus());
            }
            
            // 查询所有符合条件的数据
            List<User> users = userMapper.selectList(wrapper);
            
            // 创建工作簿
            Workbook workbook = new XSSFWorkbook();
            Sheet sheet = workbook.createSheet("员工信息");
            
            // 创建单元格样式
            CellStyle headerStyle = workbook.createCellStyle();
            Font headerFont = workbook.createFont();
            headerFont.setBold(true);
            headerFont.setFontHeightInPoints((short) 12);
            headerFont.setColor(org.apache.poi.ss.usermodel.IndexedColors.WHITE.getIndex());
            headerStyle.setFont(headerFont);
            headerStyle.setFillForegroundColor(org.apache.poi.ss.usermodel.IndexedColors.DARK_BLUE.getIndex());
            headerStyle.setFillPattern(org.apache.poi.ss.usermodel.FillPatternType.SOLID_FOREGROUND);
            headerStyle.setAlignment(org.apache.poi.ss.usermodel.HorizontalAlignment.CENTER);
            headerStyle.setVerticalAlignment(org.apache.poi.ss.usermodel.VerticalAlignment.CENTER);
            headerStyle.setBorderBottom(org.apache.poi.ss.usermodel.BorderStyle.THIN);
            headerStyle.setBorderTop(org.apache.poi.ss.usermodel.BorderStyle.THIN);
            headerStyle.setBorderLeft(org.apache.poi.ss.usermodel.BorderStyle.THIN);
            headerStyle.setBorderRight(org.apache.poi.ss.usermodel.BorderStyle.THIN);
            
            CellStyle dataStyle = workbook.createCellStyle();
            dataStyle.setBorderBottom(org.apache.poi.ss.usermodel.BorderStyle.THIN);
            dataStyle.setBorderTop(org.apache.poi.ss.usermodel.BorderStyle.THIN);
            dataStyle.setBorderLeft(org.apache.poi.ss.usermodel.BorderStyle.THIN);
            dataStyle.setBorderRight(org.apache.poi.ss.usermodel.BorderStyle.THIN);
            
            // 创建表头
            Row headerRow = sheet.createRow(0);
            String[] headers = {
                "工号", "用户名", "真实姓名", "部门", "职位", 
                "手机号", "邮箱", "性别", "生日", "账户余额", 
                "账号状态", "最后登录时间", "创建时间"
            };
            for (int i = 0; i < headers.length; i++) {
                Cell cell = headerRow.createCell(i);
                cell.setCellValue(headers[i]);
                cell.setCellStyle(headerStyle);
            }
            
            // 填充数据
            int rowNum = 1;
            for (User user : users) {
                Row row = sheet.createRow(rowNum);
                
                row.createCell(0).setCellValue(user.getEmployeeNo());
                row.createCell(1).setCellValue(user.getUsername());
                row.createCell(2).setCellValue(user.getRealName());
                row.createCell(3).setCellValue(user.getDepartment());
                row.createCell(4).setCellValue(user.getPosition());
                row.createCell(5).setCellValue(user.getPhone());
                row.createCell(6).setCellValue(user.getEmail());
                row.createCell(7).setCellValue(user.getGender() == null ? "" : (user.getGender() == 1 ? "男" : user.getGender() == 2 ? "女" : "未知"));
                row.createCell(8).setCellValue(user.getBirthday() != null ? user.getBirthday().toString() : "");
                row.createCell(9).setCellValue(user.getAccountBalance() != null ? user.getAccountBalance().toString() : "0");
                row.createCell(10).setCellValue(user.getStatus() == 1 ? "已启用" : "已禁用");
                row.createCell(11).setCellValue(user.getLastLoginTime() != null ? user.getLastLoginTime().toString() : "");
                row.createCell(12).setCellValue(user.getCreateTime() != null ? user.getCreateTime().toString() : "");
                
                // 应用样式
                for (int i = 0; i < headers.length; i++) {
                    row.getCell(i).setCellStyle(dataStyle);
                }
                
                rowNum++;
            }
            
            // 设置表头行高
            headerRow.setHeightInPoints(20);
            
            // 设置列宽
            sheet.setColumnWidth(0, 4000);  // 工号
            sheet.setColumnWidth(1, 4000);  // 用户名
            sheet.setColumnWidth(2, 4000);  // 真实姓名
            sheet.setColumnWidth(3, 3500);  // 部门
            sheet.setColumnWidth(4, 3500);  // 职位
            sheet.setColumnWidth(5, 5000);  // 手机号
            sheet.setColumnWidth(6, 5500);  // 邮箱
            sheet.setColumnWidth(7, 3000);  // 性别
            sheet.setColumnWidth(8, 4000);  // 生日
            sheet.setColumnWidth(9, 4000);  // 账户余额
            sheet.setColumnWidth(10, 3500); // 账号状态
            sheet.setColumnWidth(11, 6000); // 最后登录时间
            sheet.setColumnWidth(12, 6000); // 创建时间
            
            // 重置响应
            response.reset();
            
            // 设置CORS响应头
            response.setHeader("Access-Control-Allow-Origin", "*");
            response.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
            response.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization");
            response.setHeader("Access-Control-Allow-Credentials", "true");
            response.setHeader("Access-Control-Max-Age", "3600");
            
            // 设置内容类型
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            response.setCharacterEncoding("UTF-8");
            
            // 防止缓存
            response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate");
            response.setHeader("Pragma", "no-cache");
            response.setHeader("Expires", "0");
            
            String fileName = new String("员工数据导出.xlsx".getBytes("UTF-8"), "ISO-8859-1");
            response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
            
            // 输出文件
            try (OutputStream outputStream = response.getOutputStream()) {
                workbook.write(outputStream);
                outputStream.flush();
            } finally {
                workbook.close();
            }
            
            log.info("员工数据导出成功，共{}条记录", users.size());
            
        } catch (IOException e) {
            log.error("导出员工数据失败: {}", e.getMessage(), e);
            try {
                if (!response.isCommitted()) {
                    response.reset();
                    response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
                    response.setContentType("application/json;charset=UTF-8");
                    response.getWriter().write("{\"code\":500,\"message\":\"导出失败\"}");
                }
            } catch (Exception ignored) {
            }
        } catch (Exception e) {
            log.error("导出员工数据失败: {}", e.getMessage(), e);
            try {
                if (!response.isCommitted()) {
                    response.reset();
                    response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
                    response.setContentType("application/json;charset=UTF-8");
                    response.getWriter().write("{\"code\":500,\"message\":\"导出失败\"}");
                }
            } catch (Exception ignored) {
            }
        }
    }
}